package com.qiyun.dinghuohui.utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.PowerManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.EditText;
import android.widget.Toast;
import org.json.JSONObject;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static android.content.Context.POWER_SERVICE;

/**
 * Created by xlm on 2018\5\25 0025
 */
public class CommonUtil {

    /**
     * 忽略电池优化/Android APP杀不死（最大存活方法）
     * http://blog.csdn.net/l_o_s/article/details/56669137
     */
    @SuppressLint("BatteryLife")
    public static void ignoreBatteryOptimization(Activity activity) {
        PowerManager powerManager = (PowerManager) activity.getSystemService(POWER_SERVICE);
        boolean hasIgnored;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            hasIgnored = powerManager.isIgnoringBatteryOptimizations(activity.getPackageName());
            //  判断当前APP是否有加入电池优化的白名单，如果没有，弹出加入电池优化的白名单的设置对话框。
            if (!hasIgnored) {
                Toast.makeText(activity, "  为保证应用即时收到通知，" +
                        "请在设置中关闭本应用锁屏清理开关.", Toast.LENGTH_LONG).show();
                Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                intent.setData(Uri.parse("package:" + activity.getPackageName()));
                activity.startActivity(intent);
            }
        }
    }

    /**
     * 判断是否是网络链接
     *
     * @param url
     * @return
     */
    public static boolean checkURL(String url) {
        return url.startsWith("http") || url.startsWith("www");
    }

//    private void setTranslucentStatus() {
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 全透明实现
//            Window window = getWindow();
//            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
//                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
//            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
//            window.setStatusBarColor(Color.TRANSPARENT);
//        } else {//4.4 全透明状态栏
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//                getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//            }
//        }
//    }

    /**
     * 隐藏虚拟按键
     *
     * @param window
     */
    public static void setHideVirtualKey(Window window) {
        //保持布局状态
        int uiOptions = 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; // hide nav bar
//                    | View.SYSTEM_UI_FLAG_FULLSCREEN; // hide status bar
        }
        if (Build.VERSION.SDK_INT >= 19) {
            uiOptions |= 0x00001000;
        } else {
            uiOptions |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
        }
        window.getDecorView().setSystemUiVisibility(uiOptions);
    }

    /**
     * 判断是否有虚拟按键
     *
     * @param context
     * @return
     */
    public static boolean checkDeviceHasNavigationBar(Context context) {
        boolean hasNavigationBar = false;
        Resources rs = context.getResources();
        int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
        if (id > 0) {
            hasNavigationBar = rs.getBoolean(id);
        }
        try {
            Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
            Method m = systemPropertiesClass.getMethod("get", String.class);
            String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
            if ("1".equals(navBarOverride)) {
                hasNavigationBar = false;
            } else if ("0".equals(navBarOverride)) {
                hasNavigationBar = true;
            }
        } catch (Exception e) {
        }
        return hasNavigationBar;
    }

    /**
     * 图片尺寸质量压缩
     *
     * @param srcPath
     */
    public static void getimage(String srcPath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        //现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
        float hh = 800f;//这里设置高度为800f
        float ww = 480f;//这里设置宽度为480f
        //缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;//设置缩放比例
        //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 512) {  //循环判断如果压缩后图片是否大于512kb,大于继续压缩
            baos.reset();//重置baos即清空baos
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%，把压缩后的数据存放到baos中
            options -= 10;//每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap1 = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
        File file = new File(srcPath);//将要保存图片的路径
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //num是输入框中的值，etNum是输入框，numBoardView是自定义的数字键盘
    public static void checknum(String num, EditText etNum) {
        if (num.length() == 1) {
            //不能以"."开头
            if (".".equals(num)) {
                etNum.setText("");
            } else {
                etNum.setText(num);
            }
        } else if ("".equals(num)) {
            etNum.setText(num);
        } else {
            String first = num.substring(0, 1);
            String second = num.substring(1, 2);
            //
            if ("0".equals(first) && !".".equals(second)) {
                //第一位是"0",第二位必须是"."
                etNum.setText("0");
            } else {
                int pointSize = 0;
                for (int i = 0; i < num.length(); i++) {
                    //得到小数点
                    String str = num.substring(i, i + 1);
                    if (str.equals(".")) {
                        pointSize++;
                    }
                }
                if (pointSize == 1) {
                    int firstPointLocation = num.indexOf(".");
                    if (firstPointLocation < num.length() - 1) {
                        //小数点后有且只有两位
                        if (num.length() - 1 - firstPointLocation >= 3) {
                            //小数点已经两位了
                            etNum.setText(num.substring(0, num.length() - 1));
                        } else {
                            etNum.setText(num);
                        }
                    } else {
                        if (num.substring(0, num.indexOf(".")).length() <= 5) {
                            etNum.setText(num);
                        }
                    }
                } else if (pointSize >= 2) {
                    //两个小数点
                    if (num.substring(0, num.indexOf(".")).length() <= 5) {
                        etNum.setText(num.substring(0, num.length() - 1));
                    }

                } else {
                    if (num.length() <= 5) {
                        etNum.setText(num);
                    }
                }
            }
        }
    }

    public static String getPathFromAssets(String name, Context context) {
        //将json数据变成字符串
        StringBuilder stringBuilder = new StringBuilder();
        try {
            //获取assets资源管理器
            AssetManager assetManager = context.getAssets();
            //通过管理器打开文件并读取
            BufferedReader bf = new BufferedReader(new InputStreamReader(assetManager.open("bank/bank.json")));
            String line;
            while ((line = bf.readLine()) != null) {
                stringBuilder.append(line);
            }
            String json = stringBuilder.toString();
            JSONObject jsonObject = new JSONObject(json);
            Iterator<String> iterator = jsonObject.keys();
            String fileName = "";
            while (iterator.hasNext()) {
                String key = iterator.next() + "";
                String value = jsonObject.optString(key);
                if (value.equals(name)) {
                    fileName = "file:///android_asset/bank/iconbank/" + key + ".png";
                    break;
                }
            }
            if ("".endsWith(fileName)) {
                fileName = "file:///android_asset/bank/iconbank/" + "BANK_default.png";
            }
            return fileName;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 截图并保存
     */
    public static boolean getAndSaveCurrentImage(Activity context, String filename) {
        //1.获取屏幕
        View decorview = context.getWindow().getDecorView();
        //保存当前窗口缓存
        decorview.setDrawingCacheEnabled(true);
        decorview.buildDrawingCache();
        Bitmap Bmp = decorview.getDrawingCache();
        //2.保存Bitmap
        //判断sd卡是否存在
        boolean sdcardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if (!sdcardExist) {
            return false;
        }
        try {
            String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
                    .getAbsolutePath() + "/" + filename + ".png";
            //创建图片文件
            File file = new File(savePath);
            if (!file.exists()) {
                file.createNewFile();
            }
            //保存图片到指定路径
            FileOutputStream fos = null;
            fos = new FileOutputStream(file);
            Bmp.compress(Bitmap.CompressFormat.PNG, 90, fos);
            fos.flush();
            fos.close();
            //把文件插入到系统图库
//            MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), file.getName(), null);
            // 最后通知图库更新
            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + file)));
//            Uri.fromFile(file)//Uri.parse("file://" + file)
            //销毁缓存信息
            decorview.destroyDrawingCache();
            decorview.setDrawingCacheEnabled(false);
            return true;
        } catch (
                Exception e)

        {
            e.printStackTrace();
            return false;
        }

    }


    //字符串格式转化
    public static String StringOpt(String str, int start, int end) {
        if (str == null || str.length() == 0) {
            return "";
        }
        char[] chars = str.toCharArray();
        StringBuilder builder = new StringBuilder();
        int i = 0;
        for (char c : chars) {
            if (i > start && i < end) {
                builder.append("*");
            } else {
                builder.append(c);
            }
            i++;
        }
        if (str.length() == 11 || IDCard.IDCardValidate(str) || str.length() >= 16) {
            return builder.toString();
        }
        //每4位数加一个空格
        return builder.toString().replaceAll(".{4}(?!$)", "$0 ");
    }

    /* ******************************** dateutil begin *************************************************** */

    /**
     * 获取当前系统时间（毫秒）
     */
    public static long getCurrentMS() {
        long ms = System.currentTimeMillis();
        return ms;
    }

    public static long getCurrentDayMS() {
        long ms = getCurrentMS();
        String dataStr = formatDate(ms, "yyyyMMdd");
        return formatDate(dataStr, "yyyyMMdd");
    }

    /**
     * 获取指定格式的当前时间，返回字符串
     *
     * @param format example:"yyyy-MM-dd HH:mm:ss"
     * @return
     */
    public static String getCurrentDate(String format) {
        String dateStr = formatDate(getCurrentMS(), format);
        return dateStr;
    }

    /**
     * 将指定时间（毫秒）格式化成指定格式
     *
     * @param ms     example："45646548"
     * @param format example:"yyyy-MM-dd HH:mm:ss"
     * @return
     */
    public static String formatDate(long ms, String format) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        Date date = new Date(ms);
        String dateStr = dateFormat.format(date);
        return dateStr;
    }

    /**
     * 将指定格式的时间（字符串）格式化成毫秒,ps：只能精确到秒(后三位会显示000)
     *
     * @param datestr
     * @param format
     * @return
     */
    public static long formatDate(String datestr, String format) {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        try {
            Date date = dateFormat.parse(datestr);
            calendar.setTime(date);
        } catch (ParseException e) {
            Date date = new Date(getCurrentMS());
            calendar.setTime(date);
        }
        long ms = calendar.getTimeInMillis();
        return ms;
    }

    /**
     * 将指定格式的时间（字符串）格式化成指定格式的时间（字符串）
     *
     * @param datestr
     * @param informat,outformat
     * @return
     */
    public static String formatDate(String datestr, String informat, String outformat) {
        long ms = formatDate(datestr, informat);
        String outStr = formatDate(ms, outformat);
        return outStr;
    }

    /**
     * 获取当前日期偏离后的日期
     *
     * @param field 单位：Calendar.DATE Calendar.MONTH Calendar.YEAR
     * @param off   偏离的数值，正负表示加减
     * @return
     */
    public static long getDateOffCurrent(int field, int off) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(field, off);
        long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 获取指定日期偏离后的日期
     *
     * @param field  单位：Calendar.DATE Calendar.MONTH Calendar.YEAR
     * @param off    偏离的数值，正负表示加减
     * @param format
     * @return
     */
    public static long getDateOff(String datestr, int field, int off, String format) {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        try {
            Date date = dateFormat.parse(datestr);
            calendar.setTime(date);
        } catch (ParseException e) {
            Date date = new Date(getCurrentMS());
            calendar.setTime(date);
        }
        calendar.add(field, off);
        long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 获取指定日期偏离后的日期
     *
     * @param field 单位：Calendar.DATE Calendar.MONTH Calendar.YEAR
     * @param off   偏离的数值，正负表示加减
     * @return
     */
    public static long getDateOff(long timems, int field, int off) {
        Calendar calendar = Calendar.getInstance();
        Date date = new Date(timems);
        calendar.setTime(date);
        calendar.add(field, off);
        long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 获得指定时间是第几周
     *
     * @return 1-7： 周日-周六
     */
    public static int getDayInWeek(String datestr, String format) {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        try {
            Date date = dateFormat.parse(datestr);
            calendar.setTime(date);
        } catch (ParseException e) {
            Date date = new Date(getCurrentMS());
            calendar.setTime(date);
        }
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * 获得指定时间是第几周
     *
     * @return 1-7： 周日-周六
     */
    public static int getDayInWeek(long timems) {
        Calendar calendar = Calendar.getInstance();
        Date date = new Date(timems);
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK);
    }


    /**
     * 获取友好时间
     * 例如：刚刚，一分钟前，半小时前，一小时前
     *
     * @return
     */
    public static String getFixedTime(long beginMillis) {
        return getFixedTime(beginMillis, "HH:mm");
    }

    public static String getFixedTime(long beginMillis, String format) {
        long second = 1000;
        long minute = 60 * second;
        long half_hour = 30 * minute;
        long hour = 2 * half_hour;
        long currentMillis = getCurrentMS();
        long off = currentMillis - beginMillis;
        if (off <= minute) {
            return "刚刚";
        } else if (off <= half_hour) {
            int num = (int) (off / minute);
            return num + "分钟前";
        } else if (off <= hour) {
            return "半小时前";
        } else if (off <= 24 * hour) {
            int num = (int) (off / hour);
            return num + "小时前";
        } else return formatDate(beginMillis, format);
    }

    public static String getStarSeat(long timems) {
        String month = formatDate(timems, "M");
        String day = formatDate(timems, "d");
        try {
            return getStarSeat(Integer.parseInt(month), Integer.parseInt(day));
        } catch (Exception e) {
            LogDebug.e(e);
            return "未知";
        }
    }

    /**
     * 通过日期来确定星座
     */
    public static String getStarSeat(int month, int day) {
        String starSeat = null;

        if ((month == 3 && day >= 21) || (month == 4 && day <= 19)) {
            starSeat = "白羊座";
        } else if ((month == 4 && day >= 20) || (month == 5 && day <= 20)) {
            starSeat = "金牛座";
        } else if ((month == 5 && day >= 21) || (month == 6 && day <= 21)) {
            starSeat = "双子座";
        } else if ((month == 6 && day >= 22) || (month == 7 && day <= 22)) {
            starSeat = "巨蟹座";
        } else if ((month == 7 && day >= 23) || (month == 8 && day <= 22)) {
            starSeat = "狮子座";
        } else if ((month == 8 && day >= 23) || (month == 9 && day <= 22)) {
            starSeat = "处女座";
        } else if ((month == 9 && day >= 23) || (month == 10 && day <= 23)) {
            starSeat = "天秤座";
        } else if ((month == 10 && day >= 24) || (month == 11 && day <= 22)) {
            starSeat = "天蝎座";
        } else if ((month == 11 && day >= 23) || (month == 12 && day <= 21)) {
            starSeat = "射手座";
        } else if ((month == 12 && day >= 22) || (month == 1 && day <= 19)) {
            starSeat = "摩羯座";
        } else if ((month == 1 && day >= 20) || (month == 2 && day <= 18)) {
            starSeat = "水瓶座";
        } else {
            starSeat = "双鱼座";
        }
        return starSeat;
    }

    /* ******************************** dateutil end *************************************************** */


    /* ******************************** stringutil begin *************************************************** */

    public static <K, V> String toString(Map<K, V> map) {
        String result = "";
        for (Map.Entry<K, V> entry : map.entrySet()) {
            result += entry.getKey() + " = " + entry.getValue() + ";";
        }
        return result;
    }

    /**
     * ascII排序和MD5加密
     *
     * @param map
     * @param urlEncode
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> String toAscIIMd5String(Map<K, V> map, boolean urlEncode) {
        String keysecret = "";
        try {
            List<Map.Entry<K, V>> infoIds = new ArrayList<>(map.entrySet());
            //对所有参数按照ascII排序
            Collections.sort(infoIds, new Comparator<Map.Entry<K, V>>() {
                @Override
                public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey().toString());
                }
            });
            //对排序后的Map以键值对拼接
            StringBuilder buf = new StringBuilder();
            for (Map.Entry<K, V> item : infoIds) {
                if (CommonUtil.isNotBlank(item.getKey().toString()) && CommonUtil.isNotBlank(item.getValue().toString())) {
                    String key = item.getKey().toString();
                    String val = item.getValue().toString();
//                    if (val.equals(ApiName.SENDSMS)
//                            || val.equals(ApiName.REGISTER)) {
//                        keysecret = ApiName.KEYSECRET;
//                    }
                    //keysecret = ApiName.KEYSECRET;
                    if (urlEncode) {
                        key = URLEncoder.encode(key, "utf-8");
                        val = URLEncoder.encode(val, "utf-8");
                        buf.append(key).append("=").append(val);
                    } else {
                        buf.append(key).append("=").append(val);
                    }
                    buf.append("&");
                }
            }
            return MD5.encode(buf.toString() + "key=" + keysecret).toUpperCase();
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * ascII排序和MD5加密
     *
     * @param map
     * @param urlEncode
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> String toAscIIMd5String(Map<K, V> map, boolean urlEncode, String keysecret) {
        try {
            List<Map.Entry<K, V>> infoIds = new ArrayList<>(map.entrySet());
            //对所有参数按照ascII排序
            Collections.sort(infoIds, new Comparator<Map.Entry<K, V>>() {
                @Override
                public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey().toString());
                }
            });
            //对排序后的Map以键值对拼接
            StringBuilder buf = new StringBuilder();
            for (Map.Entry<K, V> item : infoIds) {
                if (CommonUtil.isNotBlank(item.getKey().toString()) && CommonUtil.isNotBlank(item.getValue().toString())) {
                    String key = item.getKey().toString();
                    String val = item.getValue().toString();
                    if (urlEncode) {
                        key = URLEncoder.encode(key, "utf-8");
                        val = URLEncoder.encode(val, "utf-8");
                        buf.append(key).append("=").append(val);
                    } else {
                        buf.append(key).append("=").append(val);
                    }
                    buf.append("&");
                }
            }
            return MD5.encode(buf.toString() + "key=" + keysecret).toUpperCase();
        } catch (Exception e) {
            return "";
        }
    }

    public static boolean isBlank(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0)
            return true;
        for (int i = 0; i < strLen; i++)
            if (!Character.isWhitespace(str.charAt(i)))
                return false;

        return true;
    }

    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }


    /**
     * 判断字符串是否为空(包括null,"","null")
     *
     * @param value
     * @return
     */
    public static boolean isEmpty(String value) {
        if (value == null) {
            return true;
        }
        if (value.equals("")) {
            return true;
        }
        return value.equals("null");
    }

    /**
     * 是否全为数字
     *
     * @param str
     * @return
     */
    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(str);
        return isNum.matches();
    }

    /**
     * 正则表达式匹配
     *
     * @param str
     * @param reg
     * @return
     */
    public static boolean stringMatcher(String str, String reg) {
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(str);
        return m.matches();
    }

    /**
     * 过滤匹配的字符
     *
     * @param str
     * @param reg
     * @return
     */
    public static String stringFilter(String str, String reg) {
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(str);
        return m.replaceAll("");
    }

    public static String escape(String src) {
        int i;
        char j;
        StringBuffer tmp = new StringBuffer();
        tmp.ensureCapacity(src.length() * 6);
        for (i = 0; i < src.length(); i++) {
            j = src.charAt(i);
            if (Character.isDigit(j) || Character.isLowerCase(j)
                    || Character.isUpperCase(j))
                tmp.append(j);
            else if (j < 256) {
                tmp.append("%");
                if (j < 16)
                    tmp.append("0");
                tmp.append(Integer.toString(j, 16));
            } else {
                tmp.append("%u");
                tmp.append(Integer.toString(j, 16));
            }
        }
        return tmp.toString();
    }


    public static String unescape(String src) {
        StringBuffer tmp = new StringBuffer();
        tmp.ensureCapacity(src.length());
        int lastPos = 0, pos = 0;
        char ch;
        while (lastPos < src.length()) {
            pos = src.indexOf("%", lastPos);
            if (pos == lastPos) {
                if (src.charAt(pos + 1) == 'u') {
                    ch = (char) Integer.parseInt(src
                            .substring(pos + 2, pos + 6), 16);
                    tmp.append(ch);
                    lastPos = pos + 6;
                } else {
                    ch = (char) Integer.parseInt(src
                            .substring(pos + 1, pos + 3), 16);
                    tmp.append(ch);
                    lastPos = pos + 3;
                }
            } else {
                if (pos == -1) {
                    tmp.append(src.substring(lastPos));
                    lastPos = src.length();
                } else {
                    tmp.append(src.substring(lastPos, pos));
                    lastPos = pos;
                }
            }
        }
        return tmp.toString();
    }

    public static String formatDecimal(double d, String format) {
        DecimalFormat decimalFormat = new DecimalFormat(format);
        return decimalFormat.format(d);
    }

    public static String formatDecimal(float d, String format) {
        DecimalFormat decimalFormat = new DecimalFormat(format);
        return decimalFormat.format(d);
    }


    /**
     * 判断是否为手机号
     *
     * @param mobiles
     * @return
     */
    public static boolean isMobile(String mobiles) {
        Pattern p = Pattern.compile("^(13[0-9]|14[57]|15[0-35-9]|17[0-8]|18[0-9])[0-9]{8}$");
        Matcher m = p.matcher(mobiles);
        return m.matches();
    }
    /* ******************************** stringutil end *************************************************** */

    /* ******************************** 数据转换 begin *************************************************** */

    public static InputStream byte2Input(byte[] buf) {
        return new ByteArrayInputStream(buf);
    }

    public static InputStream String2Input(String s) {
        return new ByteArrayInputStream(s.getBytes());
    }


    public static byte[] Input2byte(InputStream inStream)
            throws IOException {
        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        byte[] buff = new byte[100];
        int rc = 0;
        while ((rc = inStream.read(buff, 0, 100)) > 0) {
            swapStream.write(buff, 0, rc);
        }
        byte[] in2b = swapStream.toByteArray();
        return in2b;
    }

    public static String Input2String(InputStream inStream)
            throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(inStream));
        StringBuffer buffer = new StringBuffer();
        String line = "";
        while ((line = in.readLine()) != null) {
            buffer.append(line);
        }
        return buffer.toString();
    }

    public static byte[] File2byte(String filePath) throws IOException {
        byte[] buffer = null;
        File file = new File(filePath);
        FileInputStream fis = new FileInputStream(file);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        int n;
        while ((n = fis.read(b)) != -1) {
            bos.write(b, 0, n);
        }
        fis.close();
        bos.close();
        buffer = bos.toByteArray();
        return buffer;
    }

    public static void byte2File(byte[] buf, String filePath, String fileName) throws IOException {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        File dir = new File(filePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        file = new File(filePath + File.separator + fileName);
        fos = new FileOutputStream(file);
        bos = new BufferedOutputStream(fos);
        bos.write(buf);
        if (bos != null) {
            bos.close();
        }
        if (fos != null) {
            fos.close();
        }
    }

    public static void byteWriteInFile(byte[] buf, BufferedOutputStream bos) throws IOException {
        bos.write(buf);
    }

    public static void Input2File(InputStream input, String filePath, String fileName) throws IOException {
        File file = null;
        File dir = new File(filePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        file = new File(filePath + File.separator + fileName);
        FileOutputStream fos = new FileOutputStream(file.getPath());
        int ch = 0;
        while ((ch = input.read()) != -1) {
            fos.write(ch);
        }
        if (fos != null) {
            fos.close();
        }
        if (input != null) {
            input.close();
        }
    }

    public static InputStream File2Input(File file) throws FileNotFoundException {
        return new FileInputStream(file);
    }

    public static final String bytesToHexString(byte[] bArray) {
        StringBuffer sb = new StringBuffer(bArray.length);
        String sTemp;
        for (int i = 0; i < bArray.length; i++) {
            sTemp = Integer.toHexString(0xFF & bArray[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

    public static byte[] hexStringToByte(String hex) {
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] achar = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
        }
        return result;
    }

    private static byte toByte(char c) {
        byte b = (byte) "0123456789ABCDEF".indexOf(c);
        return b;
    }

    /* ******************************** 数据转换 end *************************************************** */


    /* ******************************** list begin *************************************************** */

    /**
     * 判断一个list是否为null,是否有数据
     *
     * @param list
     * @return
     */
    public static boolean isEmpty(List list) {
        if (list == null) {
            return true;
        }
        return list.size() == 0;
    }

    public static boolean isEmpty(Object[] list) {
        if (list == null) {
            return true;
        }
        return list.length == 0;
    }

    public static boolean isEmpty(Map list) {
        if (list == null) {
            return true;
        }
        return list.size() == 0;
    }

    /* ******************************** list end *************************************************** */


    /* ******************************** file begin *************************************************** */

    /**
     * 目录大小,文件夹大小
     *
     * @return
     */
    public static long getFileSize(String file) {
        File filef = new File(file);
        return getFileSize(filef);
    }

    /**
     * @return
     */
    public static long getFileSize(File file) {
        if (!file.exists()) {
            return 0;
        } else if (file.isDirectory()) {
            File[] files = file.listFiles();
            long size = 0;
            for (File child : files) {
                size += getFileSize(child);
            }
            return size;
        } else {
            return file.length();
        }
    }

    public static boolean deleteFile(String file) {
        File filef = new File(file);
        return deleteFile(filef);
    }

    public static boolean deleteFile(File file) {
        if (!file.exists()) {
            return true;
        } else if (file.isDirectory()) {
            File[] files = file.listFiles();
            boolean result = true;
            for (File child : files) {
                if (!deleteFile(child)) {
                    result = false;
                    break;
                }
            }
            return result;
        } else {
            return file.delete();
        }
    }

    public static boolean deleteFileAndDir(String file) {
        File filef = new File(file);
        return deleteFileAndDir(filef);
    }

    public static boolean deleteFileAndDir(File file) {
        if (file == null || file.exists()) {
            return true;
        }
        if (file.isFile()) {
            return file.delete();
        }
        File[] files = file.listFiles();
        if (files != null) {
            for (File child : files) {
                deleteFileAndDir(child);
            }
        }
        return file.delete();
    }


    public static void copyFile(String fromPath, String toPath) throws IOException {
        File from = new File(fromPath);
        if (!from.exists()) {
            return;
        }
        File toFile = new File(toPath);
        IOUtil.deleteFileOrDir(toFile);
        File toDir = toFile.getParentFile();
        if (toDir.exists() || toDir.mkdirs()) {
            FileInputStream in = null;
            FileOutputStream out = null;
            try {
                in = new FileInputStream(from);
                out = new FileOutputStream(toFile);
                int len = 0;
                byte[] buffer = new byte[1024];
                while ((len = in.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
                out.flush();
            } catch (Exception ex) {
                LogDebug.e(ex);
            } finally {
                IOUtil.closeQuietly(in);
                IOUtil.closeQuietly(out);
            }
        }
    }

    /**
     * 复制文件到指定文件
     *
     * @param fromPath 源文件
     * @param toPath   复制到的文件
     * @return true 成功，false 失败
     */
    public static boolean copyFileResult(String fromPath, String toPath) {
        boolean result = false;
        File from = new File(fromPath);
        if (!from.exists()) {
            return result;
        }
        File toFile = new File(toPath);
        IOUtil.deleteFileOrDir(toFile);
        File toDir = toFile.getParentFile();
        if (toDir.exists() || toDir.mkdirs()) {
            FileInputStream in = null;
            FileOutputStream out = null;
            try {
                in = new FileInputStream(from);
                out = new FileOutputStream(toFile);
                int len = 0;
                byte[] buffer = new byte[1024];
                while ((len = in.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
                out.flush();

                result = true;
            } catch (Exception ex) {
                LogDebug.e(ex);
                result = false;
            } finally {
                IOUtil.closeQuietly(in);
                IOUtil.closeQuietly(out);
            }
        }
        return result;
    }

    /**
     * 合并文件
     *
     * @param tempFiles 合并的文件列表
     * @param filePath  合并后文件路径
     * @return
     */
    public static File mergerFile(ArrayList<File> tempFiles, String filePath) {

        File file = new File(filePath);
//        file.deleteOnExit();
        if (file.exists()) {
            if (!file.delete()) {
                LogDebug.d("删除文件失败");
            }

        }
        // 合并文件
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(filePath);
            for (int i = 0; i < tempFiles.size(); i++) {
                // 分块文件路径
                String pieceFilePath = tempFiles.get(i).getPath();

                //读取分块文件
                FileInputStream fis = null;
                try {
                    fis = new FileInputStream(pieceFilePath);

                    byte[] buf = new byte[1024];
                    int len = 0;
                    while ((len = fis.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                } catch (IOException e) {
                    LogDebug.e(e);
                } finally {
                    fis.close();
                }
            }
            //完成分块文件合并
            return file;
        } catch (IOException e) {
            LogDebug.e(e);
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                LogDebug.e(e);
            } catch (Exception e) {
                LogDebug.e(e);
            }
        }
        return null;
    }

    /**
     * 合并文件
     *
     * @param tempFiles 合并的文件列表
     * @param filePath  合并后文件路径
     * @return
     */
    public static File mergerFile(ArrayList<File> tempFiles, String filePath, boolean deletetemp) {

        File file = new File(filePath);
//        file.deleteOnExit();
        if (file.exists()) {
            if (!file.delete()) {
                LogDebug.d("删除文件失败");
            }

        }
        // 合并文件
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(filePath);
            for (int i = 0; i < tempFiles.size(); i++) {
                // 分块文件路径
                String pieceFilePath = tempFiles.get(i).getPath();

                //读取分块文件
                FileInputStream fis = null;
                try {
                    fis = new FileInputStream(pieceFilePath);

                    byte[] buf = new byte[1024];
                    int len = 0;
                    while ((len = fis.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                    if (deletetemp) {
                        tempFiles.get(i).delete();
                    }
                } catch (IOException e) {
                    LogDebug.e(e);
                } finally {
                    fis.close();
                }
            }
            //完成分块文件合并
            return file;
        } catch (IOException e) {
            LogDebug.e(e);
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                LogDebug.e(e);
            } catch (Exception e) {
                LogDebug.e(e);
            }
        }
        return null;
    }

    /**
     * 分割文件
     *
     * @param filePath  源文件路径
     * @param tempDir   临时文件路径
     * @param blocksize 分块大小
     * @return
     */
    public static ArrayList<File> splitFile(String filePath, String tempDir, int blocksize) {
        File tempDirF = new File(tempDir);
        if (!tempDirF.exists()) {
            tempDirF.mkdirs();
        }
        File file = new File(filePath);
        ArrayList<File> tempFiles = new ArrayList<>();
        String[] split = filePath.split("/");
        String filename = split[split.length - 1];
        String[] splitz = filename.split("\\.");
        String name = splitz[0];
        String filetype = splitz[1];
        if (file.length() > blocksize) {
            long picecount = file.length() / blocksize + (file.length() % blocksize == 0 ? 0 : 1);
            for (int i = 0; i < picecount; i++) {
                RandomAccessFile raf = null;
                FileOutputStream faos = null;
                File tempfile = new File(tempDir + "/" + name + "temp" + i + "." + filetype);
                try {
                    faos = new FileOutputStream(tempfile);
                    // 负责读取数据
                    raf = new RandomAccessFile(filePath, "r");
                    //设置缓冲大小
                    byte[] buf;
                    if (blocksize > 1024) {
                        buf = new byte[1024];
                    } else {
                        buf = new byte[blocksize];
                    }
                    //跳过的字节数
                    raf.seek(blocksize * i);
                    //读取对应文件的流
                    int length = 0;//累计读取流的长度
                    int count = 0;//一次读取的流的长度
                    while ((count = raf.read(buf)) != -1 && length < blocksize) {
                        //在分块时，判断分块文件的最后一组字节数组是否需要全部写出
                        if (blocksize - length < buf.length) {
                            faos.write(buf, 0, blocksize - length);
                            count = blocksize - length;
                        } else {
                            faos.write(buf, 0, count);
                        }
                        //已经写出的字节长度
                        length += count;
                    }
                    tempFiles.add(tempfile);
                } catch (FileNotFoundException e) {
                    LogDebug.e(e);
                } catch (IOException e) {
                    LogDebug.e(e);
                } finally {
                    try {
                        raf.close();
                        faos.close();
                    } catch (IOException e) {
                        LogDebug.e(e);
                    }
                }
            }
        } else {
            tempFiles.add(file);
        }
        return tempFiles;
    }

    /**
     * 根据索引获取文件
     *
     * @param filePath   文件路径
     * @param startIndex 读取文件字节起始索引
     */
    public static byte[] getSplitFileByte(String filePath, int startIndex, int blocksize) {

        // 根据要求读取块文件
        RandomAccessFile raf = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            // 负责读取数据
            raf = new RandomAccessFile(filePath, "r");
            //设置缓冲大小
            byte[] buf;
            if (blocksize > 1024) {
                buf = new byte[1024];
            } else {
                buf = new byte[blocksize];
            }
            //跳过的字节数
            raf.seek(startIndex * blocksize);
            //读取对应文件的流
            int length = 0;//累计读取流的长度
            int count = 0;//一次读取的流的长度
            while ((count = raf.read(buf)) != -1 && length < blocksize) {
                //在分块时，判断分块文件的最后一组字节数组是否需要全部写出
                if (blocksize - length < buf.length) {
                    baos.write(buf, 0, blocksize - length);
                    count = blocksize - length;
                } else {
                    baos.write(buf, 0, count);
                }
                //已经写出的字节长度
                length += count;
            }
            //压缩
            /*ByteArrayInputStream is = new ByteArrayInputStream(baos.toByteArray());
            compress(is, baos);*/
            return baos.toByteArray();
        } catch (FileNotFoundException e) {
            LogDebug.e(e);
        } catch (Exception e) {
            LogDebug.e(e);
        } finally {
            try {
                if (null != raf) {
                    raf.close();
                }
            } catch (Exception e) {
                LogDebug.e(e);
            }
        }
        return null;

    }

    /**
     * 分割文件
     *
     * @param filePath  源文件路径
     * @param blocksize 分块大小
     * @return
     */
    public static long splitFileCount(String filePath, int blocksize) {
        File file = new File(filePath);
        long picecount = file.length() / blocksize + (file.length() % blocksize == 0 ? 0 : 1);
        return picecount;
    }

    /* ******************************** file end *************************************************** */


    /* ******************************** array begin *************************************************** */

    /**
     * 合并两个byte[]
     *
     * @param first
     * @param second
     * @return
     */
    public static byte[] concatArray(byte[] first, byte[] second) {
        if (first == null) {
            return second;
        }
        if (second == null) {
            return first;
        }
        int flength = first.length;
        int slength = second.length;
        int length = flength + slength;
        byte[] result = new byte[length];
        for (int i = 0; i < flength; i++) {
            result[i] = first[i];
        }
        for (int i = 0; i < slength; i++) {
            result[flength + i] = second[i];
        }
        return result;
    }

    public static Field[] concatArray(Field[] first, Field[] second) {
        if (first == null) {
            return second;
        }
        if (second == null) {
            return first;
        }
        int flength = first.length;
        int slength = second.length;
        int length = flength + slength;
        Field[] result = new Field[length];
        for (int i = 0; i < flength; i++) {
            result[i] = first[i];
        }
        for (int i = 0; i < slength; i++) {
            result[flength + i] = second[i];
        }
        return result;
    }

    /* ******************************** array end *************************************************** */


    /* ******************************** 屏幕 begin *************************************************** */

    /**
     * 获取屏幕DisplayMetrics
     */
    public static DisplayMetrics getDisplayMetrics(Context context) {
        return context.getResources().getDisplayMetrics();
    }

    public static int dip2px(float dpValue, float density) {
        return (int) (dpValue * density + 0.5F);
    }

    public static int px2dip(float pxValue, float density) {
        return (int) (pxValue / density + 0.5F);
    }

    public static int dip2px(float dpValue, Context context) {
        return dip2px(dpValue, getDisplayMetrics(context).density);
    }

    public static int px2dip(float pxValue, Context context) {
        return px2dip(pxValue, getDisplayMetrics(context).density);
    }

    /**
     * 获取状态栏的高度
     */
    public static int getStatusBarHeight(Context context) {
        Class<?> c = null;
        Object obj = null;
        Field field = null;
        int x = 0, statusBarHeight = 0;
        try {
            c = Class.forName("com.android.internal.R$dimen");
            obj = c.newInstance();
            field = c.getField("status_bar_height");
            x = Integer.parseInt(field.get(obj).toString());
            statusBarHeight = context.getResources().getDimensionPixelSize(x);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return statusBarHeight;
    }

    /**
     * 获取除去状态栏的屏幕的高度
     */
    public static int getScreenHeight(Context context) {
        return getDisplayMetrics(context).heightPixels - getStatusBarHeight(context);
    }

    /* ******************************** 屏幕 end *************************************************** */


    /* ******************************** package begin *************************************************** */

    private static PackageInfo getPackageInfo(Context context) {
        PackageInfo pi = null;

        try {
            PackageManager pm = context.getPackageManager();
            pi = pm.getPackageInfo(context.getPackageName(),
                    PackageManager.GET_CONFIGURATIONS);

            return pi;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return pi;
    }

    /**
     * 版本名
     *
     * @param context
     * @return
     */
    public static String getVersionName(Context context) {
        return getPackageInfo(context).versionName;
    }

    /**
     * 版本号
     *
     * @param context
     * @return
     */
    public static int getVersionCode(Context context) {
        return getPackageInfo(context).versionCode;
    }

    /**
     * @param version1
     * @param version2
     * @return 0 相等， 1 前者大,  2后者大
     */
    public static int compareVersionName(String version1, String version2) {
        int result = 0;
        String[] v1 = version1.split("\\.");
        String[] v2 = version2.split("\\.");
        int length1 = v1.length;
        int length2 = v2.length;
        if (length1 == length2) {
            for (int i = 0; i < length1; i++) {
                int v1i = Integer.valueOf(v1[i]);
                int v2i = Integer.valueOf(v2[i]);
                if (v1i > v2i) {
                    result = 1;
                    break;
                } else if (v1i == v2i) {
                    result = 0;
                } else {
                    result = 2;
                    break;
                }
            }
        } else if (length1 < length2) {
            for (int i = 0; i < length1; i++) {
                int v1i = Integer.valueOf(v1[i]);
                int v2i = Integer.valueOf(v2[i]);
                if (v1i > v2i) {
                    result = 1;
                    break;
                } else if (v1i == v2i) {
                    result = 2;
                } else {
                    result = 2;
                    break;
                }
            }
        } else {
            for (int i = 0; i < length2; i++) {
                int v1i = Integer.valueOf(v1[i]);
                int v2i = Integer.valueOf(v2[i]);
                if (v1i > v2i) {
                    result = 1;
                    break;
                } else if (v1i == v2i) {
                    result = 1;
                } else {
                    result = 2;
                    break;
                }
            }
        }
        return result;
    }

    /**
     * 获得当前进程的名字
     *
     * @param context
     * @return 进程号
     */
    public static String getCurProcessName(Context context) {

        int pid = android.os.Process.myPid();

        ActivityManager activityManager = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);

        for (ActivityManager.RunningAppProcessInfo appProcess : activityManager
                .getRunningAppProcesses()) {

            if (appProcess.pid == pid) {
                return appProcess.processName;
            }
        }
        return null;
    }

    public static void installApk(Context context, String path) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(Uri.parse("file://" + path), "application/vnd.android.package-archive");
        context.startActivity(intent);
    }

    //获取手机DEVICE_ID
    @SuppressLint({"HardwareIds", "MissingPermission"})
    public static String getDEVICE_ID(Context context) {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if (tm != null) {
            return String.valueOf(tm.getDeviceId());
        }
        return "";
    }

    /**
     * application是否在前台
     *
     * @param context
     * @return
     */
    public static boolean isAppBackground(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
        if (!tasks.isEmpty()) {
            ComponentName topActivity = tasks.get(0).topActivity;
            if (!topActivity.getPackageName().equals(context.getPackageName())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断某个界面是否在前台
     *
     * @param activity
     * @return
     */
    public static boolean isForeground(Activity activity) {
        return isForeground(activity, activity.getClass().getName());
    }

    /**
     * 判断某个界面是否在前台
     *
     * @param context
     * @param className 某个界面名称
     */
    private static boolean isForeground(Context context, String className) {
        if (isEmpty(className)) {
            return false;
        }
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(1);
        if (list != null && list.size() > 0) {
            ComponentName cpn = list.get(0).topActivity;
            if (className.equals(cpn.getClassName())) {
                return true;
            }
        }
        return false;
    }

    /* ******************************** package end *************************************************** */

    /* ******************************** View begin *************************************************** */

    /**
     * ev是否在view的内部
     *
     * @param v
     * @param ev
     * @return
     */
    public static boolean isTouchInView(View v, MotionEvent ev) {
        float x = ev.getRawX();
        float y = ev.getRawY();
        int[] location = new int[2];
        v.getLocationOnScreen(location);
        float sy = location[1];
        float endy = v.getHeight() + sy;
        float sx = location[0];
        float endx = v.getWidth() + sx;
        return sx < x && x < endx && sy < y && y < endy;
    }

    public static float getViewDistX(View v1, View v2) {
        int[] location1 = new int[2];
        v1.getLocationOnScreen(location1);
        float sx1 = location1[0];
        int[] location2 = new int[2];
        v2.getLocationOnScreen(location2);
        float sx2 = location2[0];
        return sx1 - sx2;
    }

    public static float getViewDistY(View v1, View v2) {
        int[] location1 = new int[2];
        v1.getLocationOnScreen(location1);
        float sy1 = location1[1];
        int[] location2 = new int[2];
        v2.getLocationOnScreen(location2);
        float sy2 = location2[1];
        return sy1 - sy2;
    }

    /**
     * point是否在view的内部
     *
     * @param v
     * @param point
     * @return
     */
    public static boolean isPointInView(View v, Point point) {
        float x = point.x;
        float y = point.y;
        int[] location = new int[2];
        v.getLocationOnScreen(location);
        float sy = location[1];
        float endy = v.getHeight() + sy;
        float sx = location[0];
        float endx = v.getWidth() + sx;
        return sx < x && x < endx && sy < y && y < endy;
    }



    /* ******************************** View end *************************************************** */


}
